﻿using AutoMapper;
using Hangfire.States;
using Serilog;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using WCS_Core_Configuration;
using WCS_Entity.AutoQeuipment;
using WCS_Entity.Dto.AutoEquipmentDto;
using WCS_Entity.Dto.ComProtocolDto;
using WCS_Entity.Prorocol;
using WCS_Repository.Interface;
using WCS_Service.Interface;
using WCS_Utility.Extensions;

namespace WCS_Service.Services
{
    /// <summary>
    /// 自动化设备通信协议服务
    /// </summary>
    public class ComProtocolService : BaseService<ProtocolEntity>, IComProtocolService
    {
        private readonly IComProtocolRepository _comProtocolRepository;
        private readonly IMapper _mapper;

        public ComProtocolService(IComProtocolRepository comProtocolRepository,
                                  IMapper mapper)
        {
            _comProtocolRepository = comProtocolRepository;
            _mapper = mapper;
        }

        public async Task<ComProtocolDto> CreateComProtocolAsync(CreateComProtocolDto dto)
        {
            ComProtocolDto result = new ComProtocolDto();
            var flag = await _comProtocolRepository.ExistsAsync(c => c.protocolType == dto.protocolType
                                                                && c.messageType == dto.messageType
                                                                && c.fieldInfo == dto.fieldInfo
                                                                && c.fieldIndex == dto.fieldIndex);
            if (flag)
            {
                Log.Error($"创建通信协议的内容已经存在");
                return null;
            }

            var entity = _mapper.Map<ProtocolEntity>(dto);
            entity.createTime = DateTime.Now;

            await _comProtocolRepository.InsertAsync(entity);
            result =  _mapper.Map<ComProtocolDto>(entity);
            return result;
        }

        public async Task<bool> DeleteComProtocol(int id)
        {
            return await _comProtocolRepository.DeleteByIdAsync(id);
        }

        public async Task<List<ComProtocolDto>> QueryAllComProtocolAsync()
        {
            List<ComProtocolDto> result = new List<ComProtocolDto>();
            Expression<Func<ProtocolEntity, object>> orderEx = p => p.createTime;
            var entityInfos = await _comProtocolRepository.QueryPageAsync(null, orderEx, OrderByType.Desc,1,10);
            if (entityInfos is null || !entityInfos.Any())
            {
                Log.Error("查询所有通信协议失败");
                return null;
            }
            List<Task<ComProtocolDto>> entityList = new List<Task<ComProtocolDto>>();
            foreach (var entityInfo in entityInfos)
            {
                entityList.Add(GetDtoInfoAsync(entityInfo));
            }
            await Task.WhenAll(entityList);
            result = entityList.Select(e => e.Result).ToList();
            return result;
        }

        public async Task<ComProtocolDto> QueryComProtocolAsync(int id)
        {
            ComProtocolDto result = new ComProtocolDto();

            var entityInfo = await _comProtocolRepository.QueryByIdAsync(id);
            if (entityInfo is null)
            {
                Log.Error($"查询通信协议{id}不存在");
                return null;
            }
            result =  _mapper.Map<ComProtocolDto>(entityInfo);
            return result;
        }

        public async Task<ComProtocolDto> UpdateComProtocolAsync(UpdateComProtocolDto dto)
        {
            ComProtocolDto result = new ComProtocolDto();
            var entity = await _comProtocolRepository.QueryByIdAsync(dto.Id);
            if (entity is null)
            {
                Log.Error($"更新通信协议{dto.Id}不存在");
                return null; 
            }
            if (entity.protocolType != dto.protocolType)
            {
                entity.protocolType = dto.protocolType;
            }
            if (entity.messageType != dto.messageType)
            {
                entity.messageType = dto.messageType;
            }
            if (entity.sender != dto.sender)
            { 
                entity.sender = dto.sender;
            }
            if (entity.fieldInfo != dto.fieldInfo)
            { 
                entity.fieldInfo = dto.fieldInfo;
            }
            if (entity.fieldIndex != dto.fieldIndex)
            { 
                entity.fieldIndex = dto.fieldIndex;
            }
            if (entity.isSerialNet != dto.isSerialNet)
            {
                entity.isSerialNet = dto.isSerialNet;
            }
            if (entity.describe != dto.describe)
            {
                entity.describe = dto.describe;
            }
            if (entity.Extend1 != dto.Extend1)
            { 
                entity.Extend1 = dto.Extend1;
            }
            if (entity.Extend2 != dto.Extend2)
            {
                entity.Extend2 = dto.Extend2;
            }
            if (entity.Extend3 != dto.Extend3)
            {
                entity.Extend3 = dto.Extend3;
            }
            if (entity.Extend4 != dto.Extend4)
            {
                entity.Extend4 = dto.Extend4;
            }
            if (entity.Extend5 != dto.Extend5)
            {
                entity.Extend5 = dto.Extend5;
            }
            entity.updataTime = DateTime.Now;

            await _comProtocolRepository.UpdateAsync(entity);
            result = _mapper.Map<ComProtocolDto>(entity);
            return result;
        }

        #region private
        private async Task<ComProtocolDto> GetDtoInfoAsync(ProtocolEntity entity)
        {
            return await Task.Run(() => _mapper.Map<ComProtocolDto>(entity));
        }

        private async Task<SupportProtocolMsgDto> GetProtocolMsgAsync(string para)
        {
            SupportProtocolMsgDto result = new SupportProtocolMsgDto();
            await Task.Run(() => 
            {
                var info = para.Split(":");
                if (info is not null && info.Length == 2)
                {
                    result.protocolType = info[0];
                    result.msgTyps = info[1].Split(",")?.ToList();
                }
            });

            return result;
        }
        #endregion

        #region 查询系统支持的协议报文类型
        public async Task<List<SupportProtocolMsgDto>> QueryProtocolMsgTypeAsync()
        {
            List<SupportProtocolMsgDto> result = new List<SupportProtocolMsgDto>();
            var info = AppSettingsConstVars.ProtocolMsgType;
            if (info is null)
            {
                Log.Error($"查询系统支持的协议报文类型失败");
                return null;
            }
            var equipmentList = info.Split('-')?.ToList();
            if (equipmentList is null || !equipmentList.Any())
            {
                Log.Error($"查询系统支持的协议报文类型异常");
                return null;
            }
            List<Task<SupportProtocolMsgDto>> msgDtoList = new List<Task<SupportProtocolMsgDto>>();
            foreach (var item in equipmentList)
            {
                msgDtoList.Add(GetProtocolMsgAsync(item));
            }
            await Task.WhenAll(msgDtoList);
            result = msgDtoList.Select(m => m.Result)?.ToList();
            return result;
        }
        #endregion
    }
}
